package net.wofly.sale.commodity.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.github.stuxuhai.jpinyin.ChineseHelper;
import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinHelper;

import net.wofly.common.condition.Condition;
import net.wofly.common.condition.ConditionRelate;
import net.wofly.common.condition.ConditionUtil;
import net.wofly.common.condition.FilterCondition;
import net.wofly.common.condition.Operation;
import net.wofly.common.condition.OrderCondition;
import net.wofly.common.json.XiNiaoJSON;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.common.util.CommonStatus;
import net.wofly.common.util.GeneralHelper;
import net.wofly.common.util.Identities;
import net.wofly.common.util.PageHelper;
import net.wofly.framework.util.ResultCode;
import net.wofly.framework.util.ReturnBean;
import net.wofly.right.domain.User;
import net.wofly.right.service.IUserService;
import net.wofly.sale.commodity.domain.Brand;
import net.wofly.sale.commodity.domain.Commodity;
import net.wofly.sale.commodity.domain.CommodityChannel;
import net.wofly.sale.commodity.domain.CommodityDetailImg;
import net.wofly.sale.commodity.domain.CommodityTerminal;
import net.wofly.sale.commodity.domain.CommodityType;
import net.wofly.sale.commodity.dto.CommodityChannelDto;
import net.wofly.sale.commodity.dto.CommodityDto;
import net.wofly.sale.commodity.dto.CommodityTerminalDto;
import net.wofly.sale.commodity.repository.CommodityRepository;
import net.wofly.sale.commodity.repository.CommodityTypeRepository;
import net.wofly.sale.commodity.service.IBrandService;
import net.wofly.sale.commodity.service.ICommodityChannelService;
import net.wofly.sale.commodity.service.ICommodityDetailImgService;
import net.wofly.sale.commodity.service.ICommodityService;
import net.wofly.sale.commodity.service.ICommodityTmlService;
import net.wofly.sale.commodity.service.ICommodityTypeService;
import net.wofly.sale.commodity.util.Channel;
import net.wofly.sale.commodity.util.CommodityTerminalType;

@Service("iCommodityService")
@Transactional
public class CommodityServiceImpl implements ICommodityService {
	private String COMMODITY_PREFIX = "JL" ;
	private String COMMODITY_CHANNEL_PREFIX = "JLC" ;
	private String COMMODITY_TERMINAL_PREFIX = "JLT" ;

	@Autowired
	CommodityRepository commodityRepository;
	
	@Autowired
	CommodityTypeRepository commodityTypeRepository ;
	
	@Autowired
	ICommodityChannelService iCommodityChannelService;
	@Autowired
	IBrandService iBrandService;
	@Autowired
	ICommodityDetailImgService iCommodityDetailImgService;
	@Autowired
	ICommodityTmlService iCommodityTmlService;
	@Autowired
	ICommodityTypeService iCommodityTypeService ;
	
	@Autowired
	IUserService iUserService;

	@Override
	public Commodity save(Commodity entity) {
		return commodityRepository.save(entity);
	}

	@Override
	public void delete(Commodity entity) {
		commodityRepository.delete(entity);
	}

	@Override
	public void delete(String key) {
		commodityRepository.delete(key);
	}

	@Override
	public Commodity findOne(String key) {
		return commodityRepository.findOne(key);
	}

	@Override
	public List<Commodity> save(List<Commodity> entityList) {
		return (List<Commodity>) commodityRepository.save(entityList);
	}

	@Override
	public List<Commodity> findByStatus(Integer status) {
		return commodityRepository.findByStatus(status);
	}

	@Override
	public List<Commodity> findByCommodityTypeIDAndStatus(String commodityTypeID, Integer status) {
		return commodityRepository.findByCommodityTypeIDAndStatus(commodityTypeID,status);
	}

	@Override
	public ReturnBean<Commodity> addCommodity(CommodityDto commodityDto) throws PinyinException {
		Commodity commodity = getCommodityFromCommodityDto(commodityDto) ;
		
		List<Commodity> commoditys = commodityRepository.findByCommodityName(commodity.getCommodityName());
		if (commoditys != null && commoditys.size() > 0) {
			return new ReturnBean<>(-2, "商品名称已经存在！");
		}

		List<Commodity> commodityList = commodityRepository.findByCommodityCode(commodity.getCommodityCode());
		if (commodityList != null && commodityList.size() > 0) {
			return new ReturnBean<>(-2, "商品编码已经存在！");
		}

		ReturnBean<List<CommodityChannel>> returnBean = iCommodityChannelService.addCommodityChannels(commodity.getCommodityChannelList());
		if (!returnBean.getCode().equals(0)){
			commodity.setCommodityChannel(returnBean.getResult().get(0));
			return new ReturnBean<>(-3, returnBean.getMsg(), commodity);
		}
		//保存商品终端
		iCommodityTmlService.saveByCommodity(commodity);
		
		iCommodityDetailImgService.save(commodity) ;

		return new ReturnBean<>(0, "添加商品信息成功", commodityRepository.save(commodity));
	}

	@Override
	public ReturnBean<CommodityChannel> addCommodityChannel(CommodityChannel commodityChannel) {
		return iCommodityChannelService.addCommodityChannel(commodityChannel);
	}

	@Override
	public ReturnBean<String> delCommodity(String commodityID) {
		Commodity commodity = commodityRepository.findOne(commodityID);
		if (commodity ==null) {
			return new ReturnBean<>(0, "删除商品信息成功");
		}
			
		commodity.setStatus(0);
		commodity.setModifyDate(System.currentTimeMillis());
		commodityRepository.save(commodity);
		
		iCommodityTmlService.delByCommodityID(commodityID);
		
		iCommodityChannelService.delByCommodityID(commodityID);
	
		return new ReturnBean<>(0, "删除商品信息成功");
	}

	@Override
	public ReturnBean<String> delCommodityChannel(String commodityChannelID) {
		iCommodityChannelService.delete(commodityChannelID);
		return new ReturnBean<>(0, "删除商品渠道及价格设置成功");
	}

	@Override
	public ReturnBean<PageWrapper<Commodity>> getAllCommodityChannel(Integer pageNum, Integer pageSize, Condition condition) {
		// 获得分页对象pageable，并且在pageable中页码是从0开始，设定按照sortType升序排列
		Pageable pageable = new PageRequest(pageNum - 1, pageSize);
		Page<Commodity> page;
		if (condition != null) {
			page = commodityRepository.findAll(condition.getSpecification(), pageable);
		} else {
			page = commodityRepository.findAll(pageable);
		}
		return new ReturnBean<>(ResultCode.SUCCESS, "获取商品的所有渠道价格记录成功！", PageHelper.toPage(page));
	}

	@Override
	public ReturnBean<List<Commodity>> getCommodityByType(String commodityTypeID, Integer flag) {
		List<Commodity> commodityList;
		if (flag == 0 || flag == 1) {
			commodityList = commodityRepository.findByCommodityTypeIDLikeAndStatus(commodityTypeID, flag);
		} else if (flag == -1) {
			commodityList = commodityRepository.findByCommodityTypeIDLike(commodityTypeID);
		} else {
			return new ReturnBean<>(0, "flag的值不正确！");
		}
		
		if(!CollectionUtils.isEmpty(commodityList)) {
			for (Commodity commodity : commodityList) {
				commodity.setStatusStr(CommonStatus.getName(commodity.getStatus()));
				if (!StringUtils.isEmpty(commodity.getOptUserID())) {
					User user = iUserService.findOne(commodity.getOptUserID());
					commodity.setOptUserName(user != null ? user.getUserName() : "");
				}

				commodity.setBrand(iBrandService.findOne(commodity.getBrandID()));
				CommodityType commodityType = iCommodityTypeService.findOne(commodity.getCommodityTypeID());
				commodity.setCommodityTypeIDStr(commodityType == null ? null : commodityType.getCommodityTypeName());
			}
		}
		
		return new ReturnBean<>(0, "根据商品类型获取商品信息成功", commodityList);
	}

	@Override
	public ReturnBean<Commodity> getCommodityChannelByID(String commodityID) {
		Commodity commodity = commodityRepository.findOne(commodityID);
		if (commodity == null) {
			return new ReturnBean<>(-2, "商品不存在！");
		}

		Brand brand = iBrandService.findOne(commodity.getBrandID());
		commodity.setBrand(brand);
		List<CommodityChannel> commodityChannelList  = iCommodityChannelService.findByCommodityID(commodityID);
		if(!commodityChannelList.isEmpty()) {
			for(CommodityChannel commodityChannel:commodityChannelList) {
				commodityChannel.setChannelStr(Channel.getName(Integer.parseInt(commodityChannel.getChannel())));
			}
		}
		commodity.setCommodityChannelList(commodityChannelList);
		
		List<CommodityTerminal> commodityTerminalList  = iCommodityTmlService.findByCommodityID(commodityID);
		if(!commodityTerminalList.isEmpty()) {
			for(CommodityTerminal commodityTerminal:commodityTerminalList) {
				commodityTerminal.setCommodityTerminalTypeStr(CommodityTerminalType.getName(commodityTerminal.getCommodityTerminalType()));
			}
		}
		commodity.setCommodityTerminalList(commodityTerminalList);

		//品牌图片列表
//		List<CommodityDetailImg> brandImgs = iCommodityDetailImgService.findByCommodityIDAndImgType(commodity.getBrandID(), ImgType.品牌.getValue());
		List<CommodityDetailImg> brandImgs = iCommodityDetailImgService.findByCommodityID(commodity.getBrandID());
		//商品图片列表
//		List<CommodityDetailImg> commodityImgs = iCommodityDetailImgService.findByCommodityIDAndImgType(commodityID, ImgType.商品.getValue());
		List<CommodityDetailImg> commodityImgs = iCommodityDetailImgService.findByCommodityID(commodityID);
		//公司图片列表
//		List<CommodityDetailImg> companyImgs = iCommodityDetailImgService.findByCommodityIDAndImgType("-1", ImgType.公司.getValue());
		List<CommodityDetailImg> companyImgs = iCommodityDetailImgService.findByCommodityID("-1");
		commodity.setBrandImgs(brandImgs);
		commodity.setCommodityImgs(commodityImgs);
		commodity.setCompanyImgs(companyImgs);
		return new ReturnBean<>(0, "获取商品信息及其渠道信息成功", commodity);
	}
	
	/**
	 * 修改商品时，不需要修改终端商品信息
	 * @throws PinyinException 
	 * 
	 */
	@Override
	public ReturnBean<Commodity> updateCommodity(CommodityDto commodityDto) throws PinyinException {
		Commodity commodity = getCommodityFromCommodityDto(commodityDto) ;
		
		return updateCommodity(commodity) ;
	}
	
	private Commodity getCommodityFromCommodityDto(CommodityDto commodityDto) throws PinyinException {
		Commodity commodity = new Commodity();
		
		String maxCode = getCurrCommodityCode() ;
		
		if (StringUtils.isEmpty(commodityDto.getCommodityID())) {
			commodity.setCommodityID(Identities.uuid2());
		}else {
			commodity.setCommodityID(commodityDto.getCommodityID());
		}
		commodity.setMaxCode(maxCode);
		commodity.setBrandID(commodityDto.getBrandID());
		commodity.setCommodityCode(this.COMMODITY_PREFIX +  maxCode );
		commodity.setCommodityName(commodityDto.getCommodityName());
		commodity.setCommodityNamePinYin(PinyinHelper.getShortPinyin(commodity.getCommodityName()));
		commodity.setCommodityTypeID(commodityDto.getCommodityTypeID());
		commodity.setIsbn(commodityDto.getIsbn());
		commodity.setPic(commodityDto.getPic());
		commodity.setPrice(commodityDto.getPrice());
		commodity.setRemark(commodityDto.getRemark());
		commodity.setTaste(commodityDto.getTaste());
		commodity.setUnit(commodityDto.getUnit());
		commodity.setCapacity(commodityDto.getCapacity());
		commodity.setSpecification(commodityDto.getSpecification()) ;
		commodity.setOptUserID(commodityDto.getOptUserID());
		commodity.setModifyDate(System.currentTimeMillis());
		commodity.setStatus(1);

		List<CommodityChannel> commodityChannelList = new ArrayList<>();
		for (CommodityChannelDto commodityChannelDto : commodityDto.getCommodityChannelDtos()) {
			CommodityChannel commodityChannel = new CommodityChannel();
			
			if (StringUtils.isEmpty(commodityChannelDto.getCommodityChannelID())) {
				commodityChannel.setCommodityChannelID(Identities.uuid2());
			}else {
				commodityChannel.setCommodityChannelID(commodityChannelDto.getCommodityChannelID());
			}
			
			commodityChannel.setCommodityID(commodity.getCommodityID());
			commodityChannel.setCommodityChannelName(commodity.getCommodityName() + "-"+ Channel.getName(Integer.parseInt(commodityChannelDto.getChannel()))) ;
			commodityChannel.setCommodityChannelNamePinYin(commodity.getCommodityNamePinYin()) ;
			commodityChannel.setChannel(commodityChannelDto.getChannel());
			commodityChannel.setCommodityChannelCode(this.COMMODITY_CHANNEL_PREFIX + commodityChannelDto.getChannel() + commodity.getMaxCode());
			commodityChannel.setCommodityChannelPrise(commodityChannelDto.getCommodityChannelPrise());
			commodityChannel.setStatus(1);
			commodityChannel.setModifyDate(commodity.getModifyDate());
			commodityChannelList.add(commodityChannel);
		}
		
		commodity.setCommodityChannelList(commodityChannelList);
		commodity.setCommodityImgs(commodityDto.getCommodityImgs());
		
		if (null == commodityDto.getCommodityTerminalDtos()) {
			return commodity ;
		}
		
		List<CommodityTerminal> commodityTerminalList = new ArrayList<>();
		List<CommodityTerminalDto> commodityTerminalDtos = commodityDto.getCommodityTerminalDtos() ;
		for (CommodityTerminalDto commodityTerminalDto:commodityTerminalDtos) {
			CommodityTerminal commodityTerminal = new CommodityTerminal();
			if (StringUtils.isEmpty(commodityTerminalDto.getCommodityTerminalID())) {
				commodityTerminal.setCommodityTerminalID(Identities.uuid2());
			}else {
				commodityTerminal.setCommodityTerminalID(commodityTerminalDto.getCommodityTerminalID());
			}
			commodityTerminal.setCommodityID(commodity.getCommodityID());
			commodityTerminal.setCommodityTerminalName(commodity.getCommodityName()  + "-"+  CommodityTerminalType.getName(Integer.parseInt(commodityTerminalDto.getCommodityTerminalType())));
			commodityTerminal.setCommodityTerminalNamePinYin(commodity.getCommodityNamePinYin());
			commodityTerminal.setCommodityTerminalType(Integer.parseInt(commodityTerminalDto.getCommodityTerminalType()));
			commodityTerminal.setCommodityTerminalCode("JLT" + commodityTerminalDto.getCommodityTerminalType() + commodity.getMaxCode());
			commodityTerminal.setModifyDate(commodity.getModifyDate());
			commodityTerminal.setStatus(1);
			commodityTerminal.setHasCommodityTerminal(commodityTerminalDto.getHasCommodityTerminal());
			commodityTerminalList.add(commodityTerminal);
		}
		
		commodity.setCommodityTerminalList(commodityTerminalList);
		
		return commodity ;
	}
	
	@Override
	public ReturnBean<Commodity> updateCommodity(Commodity commodity) {
		Commodity dbCommodity = commodityRepository.findOne(commodity.getCommodityID());
		if (dbCommodity == null) {
			return new ReturnBean<>(-2, "要修改的商品不存在！");
		}
		
		List<Commodity> commoditys = commodityRepository.findByCommodityName(commodity.getCommodityName());
		if (commoditys != null && commoditys.size() > 0) {
			for (Commodity entity : commoditys) {
				if (!entity.getCommodityID().equals(dbCommodity.getCommodityID())) {
					return new ReturnBean<>(-3, "修改后的商品名称已经存在！");
				}
			}
		}
		
		List<Commodity> commodityList = commodityRepository.findByCommodityCode(commodity.getCommodityCode());
		if (commodityList != null && commodityList.size() > 0) {
			for (Commodity entity : commodityList) {
				if (!entity.getCommodityID().equals(dbCommodity.getCommodityID())) {
					return new ReturnBean<>(-3, "修改后的商品编码已经存在！");
				}
			}
		}

		commodity.setCommodityCode(dbCommodity.getCommodityCode());
		commodity.setModifyDate(System.currentTimeMillis());

		ReturnBean<List<CommodityChannel>> returnBean = iCommodityChannelService.updateCommodityChannels(commodity);
		if (!returnBean.getCode().equals(0)){
			commodity.setCommodityChannel(returnBean.getResult().get(0));
			return new ReturnBean<>(-3, returnBean.getMsg(), commodity);
		}
		
		iCommodityTmlService.updateCommodityTerminal(commodity);
		
		iCommodityDetailImgService.save(commodity) ;

		return new ReturnBean<>(0, "修改商品信息成功", commodityRepository.save(commodity));
	}

	@Override
	public ReturnBean<CommodityChannel> updateCommodityChannel(CommodityChannel commodityChannel) {
		return iCommodityChannelService.updateCommodityChannel(commodityChannel);
	}

	@Override
	public Map<String ,Commodity> getAllByStatus(Integer status) {
		Map<String ,Commodity> map = new HashMap<>(); 
		List<Commodity> commodityList = commodityRepository.getAllByStatus(status);
		if (commodityList.isEmpty()) {
			return map;
		}
		
		Iterator<Commodity> it = commodityList.iterator() ;
		Commodity commodity ;
		while(it.hasNext()) {
			commodity = it.next() ;
			map.put(commodity.getCommodityID(), commodity) ;
		}
		
		return map;
	}

	@Override
	public ReturnBean<Commodity> getCommodityByID(String commodityID) {
		Commodity commodity = commodityRepository.findOne(commodityID) ;
		
		if (null == commodity) {
			return new ReturnBean<>(-6, "获取商品详情信息失败。指定的商品不存在！ id = " + commodityID, commodity) ;
		}
		
		if (StringUtils.isNotEmpty(commodity.getCommodityTypeID())) {
			CommodityType commodityType = commodityTypeRepository.findOne(commodity.getCommodityTypeID()) ;
			
			if (null != commodityType) {
				commodity.setCommodityTypeIDStr(commodityType.getCommodityTypeName());
			}
		}
		
		if (StringUtils.isNotEmpty(commodity.getBrandID())) {
			commodity.setBrand(iBrandService.findOne(commodity.getBrandID())) ;
		}
		
		commodity.setCommodityChannelList(iCommodityChannelService.findByCommodityID(commodityID)) ;
		
		commodity.setCommodityTerminalList(iCommodityTmlService.findByCommodityID(commodityID));
		
		commodity.setCommodityImgs(iCommodityDetailImgService.findByCommodityID(commodityID));
		
		return new ReturnBean<>(0, "获取商品详情信息成功", commodity) ;
	}
	
	private String getCurrCommodityCode() {
		String maxCommodityCode = commodityRepository.findMaxCommodityCode() ;
		
		if (StringUtils.isEmpty(maxCommodityCode) || maxCommodityCode.length()<6) {
			return "0001" ;
		}
		
		String maxCode = maxCommodityCode.substring(2) ;
		
		Integer maxCodeInt = Integer.parseInt(maxCommodityCode.substring(2)) + 1 ;
		
		maxCode =  "0000" + String.valueOf(maxCodeInt) ;
		maxCode =  maxCode.substring(maxCode.length()-4) ;
		
		return maxCode ;
	}

	@Override
	public PageWrapper<Commodity> getCommodityByPage(String commodityName, String commodityTypeID,Integer status, Integer pageNum, Integer pageSize) {
		Condition condition = new Condition();
        List<FilterCondition> filterConditionList = new ArrayList<>();
        List<OrderCondition> orderConditions = new ArrayList<>();
        if (StringUtils.isNotBlank(commodityName)) {
        		if (GeneralHelper.isChinese(commodityName)) {
        			filterConditionList.add(new FilterCondition(commodityName, "commodityName", ConditionRelate.and.name(), Operation.like.name(), 1));
        		}else {
        			filterConditionList.add(new FilterCondition(commodityName, "commodityNamePinYin", ConditionRelate.and.name(), Operation.like.name(), 1));
        		}
        		
        }
        if (commodityTypeID != null) {
            filterConditionList.add(new FilterCondition(commodityTypeID, "commodityTypeID", ConditionRelate.and.name(), Operation.eq.name(), 2));
        }
        if (status != null) {
            filterConditionList.add(new FilterCondition(String.valueOf(status), "status", ConditionRelate.and.name(), Operation.eq.name(), 3));
        }
        condition.setFilterCondition(filterConditionList);
        
        condition = ConditionUtil.buildCondition(XiNiaoJSON.toJSONString(condition), Commodity.class).getResult();

        List<Order> orders=new ArrayList<>();
		orders.add( new Order(Direction.DESC, "commodityCode"));
		Sort sort = new Sort(orders);
        Pageable pageable = new PageRequest(pageNum - 1, pageSize, sort);
        Page<Commodity> page = commodityRepository.findAll(condition.getSpecification(), pageable);
		
		return PageHelper.toPage(page)  ;
	}

}
